﻿/*
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at 
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  
 */

using System;
using java = biz.ritter.javapi;

namespace biz.ritter.javapi.util
{

    /**
     * SortedSet is a Set which iterates over its elements in a sorted order. The
     * order is determined either by the elements natural ordering, or by a
     * {@link Comparator} which is passed into a concrete implementation at
     * construction time. All elements in this set must be mutually comparable. The
     * ordering in this set must be consistent with {@code equals} of its elements.
     * 
     * @see Comparator
     * @see Comparable
     */
    public interface SortedSet<E> : Set<E> {
    
        /**
         * Returns the comparator used to compare elements in this {@code SortedSet}.
         * 
         * @return a comparator or null if the natural ordering is used.
         */
        Comparator<E> comparator();

        /**
         * Returns the first element in this {@code SortedSet}. The first element
         * is the lowest element.
         * 
         * @return the first element.
         * @throws NoSuchElementException
         *             when this {@code SortedSet} is empty.
         */
        E first();

        /**
         * Returns a {@code SortedSet} of the specified portion of this
         * {@code SortedSet} which contains elements less than the end element. The
         * returned {@code SortedSet} is backed by this {@code SortedSet} so changes
         * to one set are reflected by the other.
         * 
         * @param end
         *            the end element.
         * @return a subset where the elements are less than {@code end}.
         * @throws ClassCastException
         *             when the class of the end element is inappropriate for this
         *             SubSet.
         * @throws NullPointerException
         *             when the end element is null and this {@code SortedSet} does
         *             not support null elements.
         */
        SortedSet<E> headSet(E end);

        /**
         * Returns the last element in this {@code SortedSet}. The last element is
         * the highest element.
         * 
         * @return the last element.
         * @throws NoSuchElementException
         *             when this {@code SortedSet} is empty.
         */
        E last();

        /**
         * Returns a {@code SortedSet} of the specified portion of this
         * {@code SortedSet} which contains elements greater or equal to the start
         * element but less than the end element. The returned {@code SortedSet} is
         * backed by this SortedMap so changes to one set are reflected by the
         * other.
         * 
         * @param start
         *            the start element.
         * @param end
         *            the end element.
         * @return a subset where the elements are greater or equal to {@code start}
         *         and less than {@code end}.
         * @throws ClassCastException
         *             when the class of the start or end element is inappropriate
         *             for this SubSet.
         * @throws NullPointerException
         *             when the start or end element is null and this
         *             {@code SortedSet} does not support null elements.
         * @throws IllegalArgumentException
         *             when the start element is greater than the end element.
         */
        SortedSet<E> subSet(E start, E end);

        /**
         * Returns a {@code SortedSet} of the specified portion of this
         * {@code SortedSet} which contains elements greater or equal to the start
         * element. The returned {@code SortedSet} is backed by this
         * {@code SortedSet} so changes to one set are reflected by the other.
         * 
         * @param start
         *            the start element.
         * @return a subset where the elements are greater or equal to {@code start} .
         * @throws ClassCastException
         *             when the class of the start element is inappropriate for this
         *             SubSet.
         * @throws NullPointerException
         *             when the start element is null and this {@code SortedSet}
         *             does not support null elements.
         */
        SortedSet<E> tailSet(E start);
    }
}
